1.    publicclass RSoundPlayer: Engine.IEngineSound;
2.    publicclass RISoundReader: IDisposable; 
3.    publicclass RWavStreamReader: RISoundReader; 
4.    publicclass RWaveOut; 
5.    publicclass RMemAlloc; 

Microsoft.WindowsCE.Forms.MessageWindow
6.    privateclass RWaveOutMsgWindow: MessageWindow 
7.    { 
8.       publicdelegatevoid Callback(IntPtr waveHdrPtr); 
9.     
10.      publicvoid SetBufferDoneCallback(Callback cb) 
11.      { 
12.        mBufferDoneCallback = cb; 
13.      } 
14.     
15.      protectedoverridevoid WndProc(ref Message m) 
16.      { 
17.        if (m.Msg == RWaveOut.MM_WOM_DONE && mBufferDoneCallback != null) 
18.          mBufferDoneCallback(m.LParam); 
19.        base.WndProc(ref m); 
20.      } 
21.     
22.      private Callback mBufferDoneCallback = null; 
23.    } 
24.     
25.    public RSoundPlayer() 
26.    { 
27.      ... 
28.      mWceMessageWindow = new RWaveOutMsgWindow(); 
29.      mWceMessageWindow.SetBufferDoneCallback( 
30.        new RWaveOutMsgWindow.Callback(this.waveOutBufferDone)); 
31.       ... 
32.    } 
33.    public RSoundPlayer() 
34.    { 
35.        mMixerEvent = new AutoResetEvent(false); 
36.        mMixerThread = new Thread(new ThreadStart(this.mixerLoop)); 
37.      mMixerThread.Start(); 
38.    } 
39.     
40.    privatevoid addSound(RISoundReader reader) 
41.    { 
42.      lock(mPlayingSounds.SyncRoot) 
43.      { 
44.        RSoundData sd = new RSoundData(reader); 
45.        mPlayingSounds.Add(sd); 
46.      } 
47.      mMixerEvent.Set(); 
48.    } 
49.     
50.    privatevoid mixerLoop() 
51.    { 
52.         while (mMixerEvent != null && mMixerEvent.WaitOne()) 
53.       ... 
54.    } 
55.    int max_data = 0; 
56.    unsafe 
57.    { 
58.       int *header = (int *) waveHdr.ToPointer(); 
59.       uint *dest32 = (uint *)(header[0]); 
60.       int size = mWaveBufferSize / 4; 
61.       while(size-- > 0) 
62.        *(dest32++) = 0x80808080; 
63.    } 
64.     
65.    lock(mPlayingSounds.SyncRoot) 
66.    { 
67.      for(int i = mPlayingSounds.Count-1; i >= 0; i--) 
68.      { 
69.        RSoundData sd = mPlayingSounds[i] as RSoundData; 
70.        int read_size = sd.mSize - sd.mOffset; 
71.        if (read_size > kReadBufferSize) 
72.          read_size = kReadBufferSize; 
73.     
74.        sd.mReader.Read(mMixerBuffer, sd.mOffset, read_size); 
75.        sd.mOffset += read_size; 
76.     
77.        unsafe 
78.        { 
79.        unchecked 
80.        { 
81.          fixed(byte *source = mMixerBuffer) 
82.          { 

83.            int *header = (int *) waveHdr.ToPointer(); 
84.            byte *dest = (byte *) (header[0]); 
85.            int rsn = read_size * mSampleSize; 
86.            if (rsn > max_data) 
87.              max_data = rsn; 
88.    
89.            byte *src = (byte *)source; 
90.            for (int c = read_size; c > 0; c--) 
91.            { 
92.              int a = (int)(*dest) + (int)(*(src)++) - 0x80; 
93.              if (a < 0) 
94.                a= 0; 
95.              else if (a > 0xFF) 
96.                a = 0xFF; 
97.              byte b = (byte)a; 
98.              for(int j = mSampleSize; j > 0; j--) 
99.                *(dest++) = b; 
100.           } 
101.         } 
102.       } 
103.    } 
104.    
105.      if (sd.mOffset >= sd.mSize) 
106.      { 
107.        if (sd.mRepeat) 
108.           sd.mOffset = 0; 
109.        else 
110.          mPlayingSounds.RemoveAt(i); 
111.      } 
112.    } 
113.  } 
114.    
115.  unsafe 
116.  { 
117.    int *header = (int *) waveHdr.ToPointer(); 
118.    header[2] = max_data; 
119.    header[4] = header[4] & (~RWaveOut.WHDR_DONE); 
120.  } 

